/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-05-18
*/
package com.rzico.order.service;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.rzico.account.entity.Payment;
import com.rzico.account.entity.Receivable;
import com.rzico.account.entity.Refunds;
import com.rzico.account.enumx.OrderTypeEnum;
import com.rzico.account.model.Attach;
import com.rzico.account.service.DepositService;
import com.rzico.account.service.PaymentService;
import com.rzico.account.service.PointService;
import com.rzico.account.service.RefundsService;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.*;
import com.rzico.basics.mapper.MemberMapper;
import com.rzico.basics.service.*;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.*;
import com.rzico.util.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.rzico.order.mapper.AskforMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <pre>
 * 退货申请单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class AskforService extends BaseServiceImpl<Askfor, String> {

    @Autowired
    private AskforMapper askforMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private AskforItemService askforItemService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private ReturnService returnService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private ReturnItemService returnItemService;

    @Autowired
    private RefundsService refundsService;

    @Autowired
    private AskforLogService askforLogService;

    @Autowired
    private OrderLogService orderLogService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private PointService pointService;

    @Autowired
    private DepositService depositService;

    @Autowired
    private VirtualProductService virtualProductService;

    @Autowired
    private DistributionService distributionService;

    @Autowired
    private DistributionItemService distributionItemService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private ProductService productService;

    @Autowired
    private CouponCodeOrderService couponCodeOrderService;

    @Autowired @Lazy
    private VirtualStockService virtualStockService;

    @Autowired
    private OrderPlanService orderPlanService;

    @Autowired @Lazy
    private BomService bomService;

    @Autowired
    private BomItemService bomItemService;

    @Override
    public BaseMapper<Askfor, String> getMapper() {
        return askforMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUseGeneratedKeys(Askfor askfor) {
        int affectCount = super.insertUseGeneratedKeys(askfor);
        if (affectCount > 0){
            for (AskforItem askforItem : askfor.getItemList()){
                askforItem.setAskforId(askfor.getId());
            }
            askforItemService.insertUseGeneratedKeyList(askfor.getItemList());
        }
        return affectCount;
    }

    /**
     *  填充数据
     * @param order
     */

    public Askfor calculate(Order order){
        Askfor askfor = new Askfor();
        askfor.setDeleted(false);
        askfor.setAddress(order.getAddress());
        askfor.setAreaName(order.getAreaName());
        askfor.setConsignee(order.getConsignee());
        askfor.setPhone(order.getPhone());
        askfor.setMemo(order.getMemo());
        askfor.setStatus(0);
        askfor.setSubPrice(order.getSubPrice());
        askfor.setSubQuantity(order.getSubQuantity());
        askfor.setPoint(order.getPoint());
        askfor.setAmountPaid(order.getAmountPaid());
        askfor.setAmountPayable(order.getAmountPayable());
        askfor.setDiscount(order.getDiscount());
        askfor.setOffsetAmount(BigDecimal.ZERO);
        askfor.setMemberId(order.getMemberId());
        askfor.setOrderId(order.getId());
        askfor.setOrderSn(order.getSn());
        askfor.setEnterpriseId(order.getEnterpriseId());
        askfor.setDeleted(false);
        askfor.setOfficeId(order.getOfficeId());
        askfor.setOperatorId(order.getOperatorId());
        askfor.setShippingMethod(order.getShippingMethod());
        askfor.setTaxType(order.getTaxType());
        askfor.setOrderMethod(order.getOrderMethod());
        askfor.setOrderDate(DateUtils.truncate(new Date(),Calendar.DATE));
        askfor.setIsAllocatedStock(false);
        askfor.setFreight(BigDecimal.ZERO);
        askfor.setLevelFreight(BigDecimal.ZERO);
        askfor.setCompanyId(order.getCompanyId());

        //明细表数据
        List<AskforItem> itemsList = new ArrayList<>();
        for (OrderItem orderItem : order.getItemList()){
            AskforItem askforItem = new AskforItem();
            askforItem.setIsGift(orderItem.getIsGift());
            askforItem.setCost(orderItem.getCost());
            askforItem.setName(orderItem.getName());
            askforItem.setPrice(orderItem.getPrice());
            askforItem.setQuantity(orderItem.getQuantity());
            askforItem.setSn(orderItem.getSn());
            askforItem.setSpec(orderItem.getSpec());
            askforItem.setUnit(orderItem.getUnit());
            askforItem.setWeight(orderItem.getWeight());
            askforItem.setThumbnail(orderItem.getThumbnail());
            askforItem.setProductId(orderItem.getProductId());
            askforItem.setAskforId(askfor.getId());
            askforItem.setDiscount(orderItem.getDiscount());
            askforItem.setPromotionId(orderItem.getPromotionId());
            askforItem.setCouponCodeId(orderItem.getCouponCodeId());
            askforItem.setSubType(orderItem.getSubType());
            askforItem.setCouponCodeQuantity(orderItem.getCouponCodeQuantity());
            //冗余存储
            itemsList.add(askforItem);
            askfor.setItemList(itemsList);
        }

        List<OrderItem> orderItemList = orderItemService.getItemList(order.getId());
        BigDecimal quanatity = BigDecimal.ZERO;
        BigDecimal returnQuanatity = BigDecimal.ZERO;
        for (OrderItem orderItem:orderItemList) {
            quanatity = orderItem.getQuantity();
            returnQuanatity = orderItem.getReturnQuantity();
        }


        askfor.setSubPrice(askfor.calculateSubPrice());
        askfor.setSubQuantity(askfor.calculateSubQuantity());
        askfor.setDiscount(askfor.calculateSubDiscount());

        if (quanatity.subtract(returnQuanatity).subtract(askfor.getSubQuantity()).compareTo(BigDecimal.ZERO)<=0) {
            askfor.setFreight(order.getFreight());
            askfor.setLevelFreight(order.getLevelFreight());
        }

        askfor.setAmountPaid(BigDecimal.ZERO);
        askfor.setAmountPayable(askfor.calculateAmountPayable());
        askfor.setIsAllocatedStock(true);

        return askfor;

    }

    @Transactional(rollbackFor = Exception.class)
    public Askfor updateOffsetAmount(Askfor askfor) {
        askfor.setItemList(askforItemService.getItemList(askfor.getId()));

        //店铺优惠+抹零，按交易金额分滩到每个商品
        BigDecimal discount = askfor.getDiscount().subtract(askfor.getOffsetAmount());
        if (discount.compareTo(BigDecimal.ZERO)>0) {
            BigDecimal balance = discount;
            BigDecimal totalAmount = askfor.getSubPrice();
            //开始分摊活动费用
            for (AskforItem orderItem : askfor.getItemList()) {
                if (orderItem.getIsGift() == false) {
                    BigDecimal d = orderItem.getAmount().
                            multiply(discount).
                            divide(totalAmount, 2, BigDecimal.ROUND_DOWN);
                    orderItem.setIsGift(false);
                    orderItem.setDiscount(d);
                    balance = balance.subtract(d);
                    askforItemService.updateByPrimaryKeySelective(orderItem);
                }
            }
            //结余没分完的，分到第一个商品中
            AskforItem orderItem = askfor.getItemList().get(0);
            orderItem.setDiscount(orderItem.getDiscount().add(balance));
            askforItemService.updateByPrimaryKeySelective(orderItem);
        }

        askfor.setAmountPayable(askfor.calculateAmountPayable());
        updateByPrimaryKeySelective(askfor);
        return askfor;
    }



    /**
     * 退货申请
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Askfor askfor(Long id,List<OrderItem> itemList,String sn,String reason,String memo){

        //1、检查销售订单是否存在
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("未查找到订单");
        }

        if (itemList!=null && itemList.size()>0) {

            //2、检查发货数量，并封装需要保存的orderItemList
            List<OrderItem> targetList = new ArrayList<>();
            for (OrderItem paramItem : itemList) {
                OrderItem target = orderItemService.selectByPrimaryKey(paramItem.getId());
                if (paramItem.getReturnQuantity().compareTo(BigDecimal.ZERO)>0) {
                    target.setQuantity(paramItem.getReturnQuantity());
                    targetList.add(target);
                }
            }

            order.setItemList(targetList);

        } else {
            itemList = orderItemService.getItemList(id);
            List<OrderItem> targetList = new ArrayList<>();
            for (OrderItem paramItem : itemList) {
                OrderItem target = orderItemService.selectByPrimaryKey(paramItem.getId());
                target.setQuantity(paramItem.getAvailableReturnQuantity());
                targetList.add(target);
            }

            order.setItemList(targetList);
        }

        Askfor askfor = insertAskfor(order,sn,reason,memo);

        writeReturnQuantity(askfor);

        Boolean v1 = virtualProductService.checkAskfor(askfor);
        if (v1==false) {
            throw new CustomException("已使用不能退");
        }

        Boolean v2 = orderPlanService.checkAskfor(askfor);
        if (v2==false) {
            throw new CustomException("已使用不能退");
        }

        //生成退货日志
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("发起退款申请");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_CREATE.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);

        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("买家申请退款");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(order.getId());
        orderLogService.insertUseGeneratedKeys(orderLog);


        return askfor;
    }


    /**
     *  生成退货申请单
     * @param order
     */
    @Transactional(rollbackFor = Exception.class)
    public Askfor insertAskfor(Order order,String sn,String reason,String memo){
        Askfor askfor = calculate(order);
        askfor.setSn(sn);
        askfor.setReason(reason);
        askfor.setMemo(memo);
        insertUseGeneratedKeys(askfor);

        return askfor;
    }

    /**
     * 生成出入库
     * @param askfor
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertWarehouse(Askfor askfor, Long shopId ,Date orderDate,String sn){

        SysUser sysUser = sysUserService.getCurrent();
        Warehouse warehouse = new Warehouse();
        warehouse.setSn(sn);
        warehouse.setOrderSn(askfor.getOrderSn());
        warehouse.setAddress(askfor.getAddress());
        warehouse.setAreaId(askfor.getAreaId());
        warehouse.setAreaName(askfor.getAreaName());
        warehouse.setConsignee(askfor.getConsignee());
        warehouse.setPhone(askfor.getPhone());
        warehouse.setMemo(askfor.getMemo());
        warehouse.setStatus(0);
        warehouse.setWarehouseType(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId());
        warehouse.setTaxType(0);
        warehouse.setMemberId(askfor.getMemberId());
        warehouse.setOrderId(askfor.getOrderId());
        warehouse.setEnterpriseId(askfor.getEnterpriseId());
        warehouse.setShopId(shopId);
        warehouse.setDeleted(false);
        warehouse.setOfficeId(askfor.getOfficeId());
        warehouse.setOperatorId(sysUser.getId());
        warehouse.setSPrint(0);
        warehouse.setSupplierId(askfor.getMemberId());
        warehouse.setAskforId(askfor.getId());
        warehouse.setOrderMethod(askfor.getOrderMethod());
        warehouse.setOrderDate(DateUtils.truncate(orderDate,Calendar.DATE));
        warehouse.setShippingMethod(askfor.getShippingMethod());

        //明细表数据
        List<WarehouseItem> itemsList = new ArrayList<>();
        for (AskforItem orderItem : askfor.getItemList()) {

            if (orderItem.getQuantity().compareTo(BigDecimal.ZERO) > 0) {
                WarehouseItem warehouseItem = new WarehouseItem();
                warehouseItem.setSubType(orderItem.getSubType());
                warehouseItem.setCost(orderItem.getCost());
                warehouseItem.setName(orderItem.getName());
                warehouseItem.setPrice(orderItem.getPrice());
                warehouseItem.setQuantity(orderItem.getQuantity());
                warehouseItem.setSn(orderItem.getSn());
                warehouseItem.setUnit(orderItem.getUnit());
                warehouseItem.setSpec(orderItem.getSpec());
                warehouseItem.setThumbnail(orderItem.getThumbnail());
                warehouseItem.setProductId(orderItem.getProductId());
                warehouseItem.setWarehouseId(warehouse.getId());
                warehouseItem.setDiscount(orderItem.getDiscount());
                //冗余存储
                warehouseItem.setShopId(warehouse.getShopId());
                warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
                warehouseItem.setTax(BigDecimal.ZERO);
                itemsList.add(warehouseItem);
            }


            if (orderItem.getSubType().equals(1)) {
                //套餐时，生成配送计划
                Bom bom = null;
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",askfor.getEnterpriseId());
                params.put("productId",orderItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                if (bomList.size()>0) {
                    bom = bomList.get(0);
                }

                if (bom==null) {
                    throw new CustomException("请设置套餐");
                }

                if (bom.getQuantity()>1) {
                    continue;
                }

                List<BomItem> bomItemList = bomItemService.getItemList(bom.getId());
                for (BomItem bomItem:bomItemList) {
                    Product product = productService.selectByPrimaryKey(bomItem.getProductId());

                    WarehouseItem warehouseItem = new WarehouseItem();
                    warehouseItem.setSubType(product.getSubType());
                    warehouseItem.setCost(product.getCost());
                    warehouseItem.setName(product.getName());
                    warehouseItem.setPrice(BigDecimal.ZERO);
                    warehouseItem.setQuantity(bomItem.getConvRate().multiply(orderItem.getQuantity()));
                    warehouseItem.setSn(product.getSn());
                    warehouseItem.setUnit(product.getUnit());
                    warehouseItem.setSpec(product.getSpec());
                    warehouseItem.setThumbnail(product.getThumbnail());
                    warehouseItem.setProductId(product.getId());
                    warehouseItem.setWarehouseId(warehouse.getId());
                    warehouseItem.setDiscount(BigDecimal.ZERO);
                    //冗余存储
                    warehouseItem.setShopId(warehouse.getShopId());
                    warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
                    warehouseItem.setTax(BigDecimal.ZERO);
                    itemsList.add(warehouseItem);

                }

            }

        }
        warehouse.setItemList(itemsList);

        warehouse.setSubPrice(warehouse.calculateSubPrice());
        warehouse.setSubQuantity(warehouse.calculateSubQuantity());

        if (warehouse.getItemList().size()>0) {
            warehouseService.insertUseGeneratedKeys(warehouse);
            warehouseService.confirm(warehouse.getId());
        }

    }

    public void undoReturnQuantity(Askfor askfor){
        Order order = orderService.selectByPrimaryKey(askfor.getOrderId());
        List<OrderItem> orderItemList = orderItemService.getItemList(order.getId());

        //销售退货单
        for (AskforItem askforItem : askfor.getItemList()) {

                //本次退货数量
                BigDecimal quantity = askforItem.getQuantity();
                for (OrderItem orderItem : orderItemList) {
                    if (orderItem.getProductId().equals(askforItem.getProductId())) {
                        //本商品剩余可退货数量
                        BigDecimal canReturnQty = orderItem.getReturnQuantity();
                        BigDecimal returnQuantity = BigDecimal.ZERO;
                        //当可退货数量大于本次退货数量，用本次退货数量
                        if (canReturnQty.compareTo(quantity) >= 0) {
                            returnQuantity = quantity;
                            orderItem.setReturnQuantity(orderItem.getReturnQuantity().subtract(returnQuantity));
                            orderItemService.updateByPrimaryKeySelective(orderItem);
                        } else {
                            //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                            returnQuantity = canReturnQty;
                            orderItem.setReturnQuantity(orderItem.getReturnQuantity().subtract(returnQuantity));
                            orderItemService.updateByPrimaryKeySelective(orderItem);
                        }
                        //剩余退货数量
                        quantity = quantity.subtract(returnQuantity);
                    }
                }
                if (quantity.compareTo(BigDecimal.ZERO) != 0) {
                    throw new CustomException("退货数量不能大于订货数量,请核对!");
                }

        }

    }

    public void writeReturnQuantity(Askfor askfor) {

        Order order = orderService.selectByPrimaryKey(askfor.getOrderId());
        List<OrderItem> orderItemList = orderItemService.getItemList(order.getId());

        //销售退货单
        for (AskforItem askforItem : askfor.getItemList()) {

                //本次退货数量
                BigDecimal quantity = askforItem.getQuantity();
                for (OrderItem orderItem : orderItemList) {
                    if (orderItem.getProductId().equals(askforItem.getProductId())) {
                        //本商品剩余可退货数量
                        BigDecimal canReturnQty = orderItem.getQuantity().subtract(orderItem.getReturnQuantity());
                        BigDecimal returnQuantity = BigDecimal.ZERO;
                        //当可退货数量大于本次退货数量，用本次退货数量
                        if (canReturnQty.compareTo(quantity) >= 0) {
                            returnQuantity = quantity;
                            orderItem.setReturnQuantity(returnQuantity.add(orderItem.getReturnQuantity()));
                            orderItemService.updateByPrimaryKeySelective(orderItem);
                        } else {
                            //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                            returnQuantity = canReturnQty;
                            orderItem.setReturnQuantity(returnQuantity.add(orderItem.getReturnQuantity()));
                            orderItemService.updateByPrimaryKeySelective(orderItem);
                        }
                        //剩余退货数量
                        quantity = quantity.subtract(returnQuantity);
                    }
                }
                if (quantity.compareTo(BigDecimal.ZERO) != 0) {
                    throw new CustomException("退货数量不能大于订货数量,请核对!");
                }

        }

    }

    /**
     *  同意退货
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int confirm(Long id) {

        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("订单不存在");
        }

        //判断是否有发货
        List<OrderItem> itemList = orderItemService.getItemList(askfor.getOrderId());
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        BigDecimal quantity = BigDecimal.ZERO;

        for (OrderItem orderItem:itemList) {
            //检查是否发货，按实物来
            if (orderItem.getSubType().equals(0) || orderItem.getSubType().equals(1)) {
                shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity());
                quantity = quantity.add(orderItem.getQuantity());
            }
        }

        if (shippingQuantity.compareTo(quantity)<0 && shippingQuantity.compareTo(BigDecimal.ZERO)>0) {
            throw new CustomException("正在发货不能退款。");
        }

        BigDecimal returnQuantity = BigDecimal.ZERO;

        askfor.setItemList(askforItemService.getItemList(askfor.getId()));

        Boolean v1 = virtualProductService.checkAskfor(askfor);
        if (v1==false) {
            throw new CustomException("已使用不能退");
        }

        Boolean v2 = orderPlanService.checkAskfor(askfor);
        if (v2==false) {
            throw new CustomException("已使用不能退");
        }

        for (AskforItem askforItem:askfor.getItemList()) {
            returnQuantity = returnQuantity.add(askforItem.getQuantity());
        }

        if (shippingQuantity.compareTo(BigDecimal.ZERO)==0) {

            //没有发货直接，不用寄回直接 签收
            askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_SHIPPED.getId());
            super.updateByPrimaryKeySelective(askfor);
            //更新退货数量，也发货也要更新订单退货数量

        } else {

            //订单确认，锁定库存
            askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_CONFIRM.getId());
            super.updateByPrimaryKeySelective(askfor);

        }

        //生成退货日志
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("卖家同意退款");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_CONFIRM.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);

        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("卖家同意退款");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        return 1;

    }


    /**
     * 寄回给商家
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int shipping(Long id,List<AskforItem> itemList){
        //1、检查销售订单是否存在
        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("未查找到订单");
        }

        //2、检查发货数量，并封装需要保存的orderItemList
        String errMsg = "";
        for (AskforItem paramItem : itemList){
            AskforItem target = askforItemService.selectByPrimaryKey(paramItem.getId());
            target.setTrackingNo(paramItem.getTrackingNo());
            int affectCount = askforItemService.updateByPrimaryKeySelective(target);
            if (affectCount==0) {
                throw new CustomException("无效商品项id");
            }
        }
        //3、更新order的shippingStatus状态
        askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_SHIPPING.getId());
        int affectCount = updateByPrimaryKeySelective(askfor);

        //生成退货日志
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("商品已寄回，等待卖家收货");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_SHIPPING.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);


        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("商品已寄回，等待卖家收货");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);


        return affectCount;
    }


    public AskforItem findBomItem(Askfor askfor,Long productId) {
        for (AskforItem askforItem:askfor.getItemList()) {
            if (askforItem.getSubType().equals(1)) {
                Map<String,Object> params = new HashMap<>();
                params.put("enterpriseId",askfor.getEnterpriseId());
                params.put("productId",askforItem.getProductId());
                List<Bom> bomList = bomService.selectList(params);
                for (Bom bom:bomList) {
                    bom.setItemList(bomItemService.getItemList(bom.getId()));
                    for (BomItem bomItem:bom.getItemList()) {
                        if (bomItem.getProductId().equals(productId)) {
                           return askforItem;
                        }
                    }
                }
            }
        }
        return null;
    }


    /**
     * 退货入库
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int received(Long id,Long shopId,Date orderDate,String sn){

        //1、检查销售订单是否存在
        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("未查找到订单");
        }

        //3、更新order的shippingStatus状态
        askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_SHIPPED.getId());
        int affectCount = updateByPrimaryKeySelective(askfor);

        //判断是否有发货

        askfor.setItemList(askforItemService.getItemList(askfor.getId()));

        //收到货到生成退款单  待完成
        insertWarehouse(askfor,shopId,orderDate,sn);

        //处理物流单号
        Map<String,Object> params = new HashMap<>();
        params.put("askforId",askfor.getId());
        List<Return> returnsList = returnService.selectList(params);

        for (Return rt:returnsList) {
            rt.setItemList(returnItemService.getItemList(rt.getId()));
            for (ReturnItem returnItem:rt.getItemList()) {
                    AskforItem askforItem = askfor.findAskforItem(returnItem.getProductId());
                    if (askforItem==null) {
                        askforItem = findBomItem(askfor,returnItem.getProductId());
                    }
                    if (askforItem != null) {
                        returnItem.setTrackingNo(askforItem.getTrackingNo());
                        returnItemService.updateByPrimaryKeySelective(returnItem);
                    }
            }
        }

        //生成退货日志
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("商品已退货，等待卖家退款");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_RECEIVED.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);


        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("商品已退货，等待卖家退款");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        return affectCount;

    }

    /**
     * 关闭退款
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int cancel(Long id) {

        //1、检查销售订单是否存在
        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("未查找到订单");
        }

        if     (!askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_UNCONFIRM.getId())
                && !askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_CONFIRM.getId())
                && !askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_SHIPPED.getId())
                ) {
            throw new CustomException("不能关闭");
        }

        //如果待退款时取消，需检查退货单是否完成退货
        //检查是否收货完毕
        Map<String,Object> params = new HashMap<>();
        params.put("askforId",id);

        List<Return> returnList = returnService.selectList(params);
        if (returnList.size()>0) {
            throw new CustomException("已退货不能关闭");
        }

        List<Warehouse> warehouseList = warehouseService.selectList(params);
            for (Warehouse warehouse:warehouseList) {
                if (!warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_COMPLETE.getId())){
                    throw new CustomException("已退货不能关闭!");
                }


                if (warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_CONFIRM.getId())) {
                    warehouseService.cancel(warehouse.getId());
                }
            }


        askfor.setItemList(askforItemService.getItemList(askfor.getId()));
        undoReturnQuantity(askfor);

        askfor.setIsAllocatedStock(false);


        //3、更新order的shippingStatus状态
        askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_CANCLEED.getId());
        int affectCount = updateByPrimaryKeySelective(askfor);

        //关闭退货单
        returnService.cancelAskfor(id);

        //关闭退款申请
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("买家撤消退款申请");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_CANCEL.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);


        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("买家撤消退款申请");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        return affectCount;

    }


    /**sf
     * 拒绝退款
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int reject(Long id) {

        //1、检查销售订单是否存在
        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("未查找到订单");
        }

        if     (!askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_UNCONFIRM.getId())
                && !askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_CONFIRM.getId())
                && !askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_SHIPPED.getId())
                ) {
            throw new CustomException("不能拒绝");
        }


        Map<String,Object> params = new HashMap<>();
        params.put("askforId",id);

        List<Warehouse> warehouseList = warehouseService.selectList(params);
        for (Warehouse warehouse:warehouseList) {

            if (warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_COMPLETE.getId())) {
                warehouseService.disAudit(warehouse.getId());
                warehouseService.cancel(warehouse.getId());
            }

            if (warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_CONFIRM.getId())) {
                warehouseService.cancel(warehouse.getId());
            }
        }


        askfor.setItemList(askforItemService.getItemList(askfor.getId()));

        undoReturnQuantity(askfor);

        askfor.setIsAllocatedStock(false);

        //3、更新order的shippingStatus状态
        askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_CANCLEED.getId());
        int affectCount = updateByPrimaryKeySelective(askfor);

        //关闭退货单
        returnService.cancelAskfor(id);


        //关闭退款申请
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("卖家拒绝退款,如有疑问请咨询客服");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_CANCEL.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);


        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_RETURN.getId());
        orderLog.setContent("卖家拒绝退款,如有疑问请咨询客服");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);


        return affectCount;

    }

    @Transactional(rollbackFor = Exception.class)
    public void startCalcPoint(Long askforId) {

        Askfor askfor = super.selectByPrimaryKey(askforId);

        Order order = orderService.selectByPrimaryKey(askfor.getOrderId());


        if (order.getGroupBuyId()!=null) {
            return;
        }

        if (order.getGiftCardId()!=null) {
            return;
        }

        if (order.getBargainBuyId()!=null) {
            return;
        }


        Distribution defDistribution = distributionService.getDefault(askfor.getEnterpriseId());
        if (defDistribution==null) {
            return;
        }
        if (defDistribution.getStatus().equals(1)) {
            return;
        }

        askfor.setItemList(askforItemService.getItemList(askforId));

        Member member = memberService.findById(order.getMemberId());

        Member p1 = memberService.findById(order.getPromoterId1());

        Member p2 = memberService.findById(order.getPromoterId2());

        Member ag1 = memberService.findById(order.getAgentId1());

        BigDecimal a1 = BigDecimal.ZERO;
        BigDecimal a2 = BigDecimal.ZERO;
        BigDecimal t2 = BigDecimal.ZERO;
        BigDecimal d1 = BigDecimal.ZERO;
        BigDecimal my = BigDecimal.ZERO;

        for (AskforItem askforItem:askfor.getItemList()) {
            BigDecimal amount = askforItem.getSubTotal();
            if (askforItem.getIsGift()==false && !askforItem.getSubType().equals(3) && amount.compareTo(BigDecimal.ZERO)>0) {
                Product product = productService.selectByPrimaryKey(askforItem.getProductId());
                Distribution distribution = defDistribution;
                if (product.getDistributionId() != null) {
                    distribution = distributionService.findById(product.getDistributionId());
                }
                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));
                if (p1!=null) {
                    a1 = a1.add(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.add(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.add(amount.multiply(distribution.getVPeerRate(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.add(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }
                my = my.add(amount.multiply(distribution.getGiven()));
            }
        }

        //扣除水票及电子券支付
        Map<String,Object> paymentParams = new HashMap<>();
        paymentParams.put("orderType",0);
        paymentParams.put("askforId",askforId);
        List<Refunds> refundsList = refundsService.selectList(paymentParams);
        Distribution distribution = defDistribution;
        for (Refunds refunds:refundsList) {
            if (refunds.getPaymentPluginId().equals("waterTicketPayPlugin")) {
                Attach attach = refunds.decodeAttach();
                Product product = productService.selectByPrimaryKey(attach.getProductId());
                if (product.getDistributionId() != null) {
                    distribution = distributionService.selectByPrimaryKey(product.getDistributionId());
                }
                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));
                BigDecimal amount = refunds.getAmount();
                if (p1!=null) {
                    a1 = a1.subtract(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.subtract(amount.multiply(distribution.getVPeerRate(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.subtract(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }

                my = my.subtract(amount.multiply(distribution.getGiven()));
            }
            if (refunds.getPaymentPluginId().equals("couponCodePayPlugin")) {
                Attach attach = refunds.decodeAttach();
                Product product = productService.selectByPrimaryKey(attach.getProductId());
                if (product.getDistributionId() != null) {
                    distribution = distributionService.findById(product.getDistributionId());
                }
                distribution.setItemList(distributionItemService.getItemList(distribution.getId()));
                BigDecimal amount = refunds.getAmount();
                if (p1!=null) {
                    a1 = a1.subtract(amount.multiply(distribution.getVPercent1(p1.vipObject())));
                }
                if (p2!=null) {
                    a2 = a2.subtract(amount.multiply(distribution.getVPercent2(p2.vipObject())));
                    t2 = t2.subtract(amount.multiply(distribution.getVPeerRate(p2.vipObject())));
                }
                if (ag1!=null) {
                    d1 = d1.subtract(amount.multiply(distribution.getVAgent1(ag1.vipObject())));
                }
                my = my.subtract(amount.multiply(distribution.getGiven()));
            }
        }


        if (order.getRebate1().compareTo(BigDecimal.ZERO)>=0) {
            if (order.getRebate1().compareTo(a1)<0) {
                a1 = order.getRebate1();
            }
            if (a1.compareTo(BigDecimal.ZERO) > 0 && p1 != null) {
                order.setRebate1(order.getRebate1().subtract(a1));
                pointService.decPoint(p1.getId(), a1.longValue(), "退还1级佣金-贡献会员:".concat(member.getName()), 0, order.getId());
                pointService.decFreezePoint(p1.getId(), a1.longValue());
            }
        }


        if (order.getRebate2().compareTo(BigDecimal.ZERO)>=0) {
            if (order.getRebate2().compareTo(a2)<0) {
                a2 = order.getRebate2();
            }
            if (a2.compareTo(BigDecimal.ZERO) > 0 && p2 != null && p2.getVvip().compareTo(p1.getVvip())>0) {
                order.setRebate2(order.getRebate2().subtract(a2));
                pointService.decPoint(p2.getId(), a2.longValue(), "退还2级佣金-贡献会员:".concat(p1.getName()), 0, order.getId());
                pointService.decFreezePoint(p2.getId(), a2.longValue());
            }
        }

        if (order.getRebate2().compareTo(BigDecimal.ZERO)>=0) {
            if (order.getRebate2().compareTo(a2)<0) {
                a2 = order.getRebate2();
            }
            if (a2.compareTo(BigDecimal.ZERO) > 0 && p2 != null && p2.getVvip().compareTo(p1.getVvip())==0) {
                order.setRebate2(order.getRebate2().subtract(a2));
                pointService.decPoint(p2.getId(), a2.longValue(), "退还2级佣金-贡献会员:".concat(p1.getName()), 0, order.getId());
                pointService.decFreezePoint(p2.getId(), a2.longValue());
            }
        }


        if (order.getAgent1().compareTo(BigDecimal.ZERO)>=0) {
            if (order.getAgent1().compareTo(d1)<0) {
                d1 = order.getAgent1();
            }
            if (d1.compareTo(BigDecimal.ZERO) > 0 && ag1 != null) {
                order.setAgent1(order.getAgent1().subtract(d1));
                pointService.decPoint(ag1.getId(), d1.longValue(), "退还代理佣金-贡献会员:".concat(p1.getName()), 0, order.getId());

                pointService.decFreezePoint(ag1.getId(), d1.longValue());
            }
        }

        if (order.getPoint().compareTo(0L)>=0) {

            if (order.getPoint().compareTo(my.longValue())<0) {
                my = new BigDecimal(order.getPoint());
            }

            if (my.compareTo(BigDecimal.ZERO) > 0 && member != null) {
                order.setPoint(order.getPoint() - my.longValue());
            //    pointService.decPoint(member.getId(), my.longValue(), "退还购买返利-".concat(askfor.getTitle()), 0, order.getId());
            //    pointService.decFreezePoint(member.getId(), my.longValue());
            }

        }

        orderService.updateByPrimaryKeySelective(order);

    }

    //开始退款结算
    @Transactional(rollbackFor = Exception.class)
    public void startDistribution(Long askforId) {

        Askfor askfor  = askforMapper.selectByPrimaryKey(askforId);

        askfor.setItemList(askforItemService.getItemList(askforId));

        Enterprise enterprise = enterpriseService.selectByPrimaryKey(askfor.getEnterpriseId());
        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
        if (sysMch.getMchType().equals(2)) {

            Member member = memberService.selectByPrimaryKey(enterprise.getMemberId());

            //退还供货商货款
            BigDecimal cost = BigDecimal.ZERO;
            List<AskforItem> askforItemList = askfor.getItemList();
            String title = null;
            for (AskforItem askforItem:askforItemList) {
                Product product = productService.selectByPrimaryKey(askforItem.getProductId());
                if (product.getPublishType().equals(1)) {
                    BigDecimal subCost = askforItem.calculateSubCost();
                    if (subCost.compareTo(BigDecimal.ZERO)>0) {
                        title = askforItem.getName();
                        cost = cost.add(askforItem.calculateSubCost());
                    }

                }
            }

            // 特约商户，结算货款
            Map<String,Object> paymentParams = new HashMap<>();
            paymentParams.put("orderType",0);
            paymentParams.put("askforId",askforId);
            List<Refunds> refundsList = refundsService.selectList(paymentParams);
            BigDecimal amount = BigDecimal.ZERO;
            for (Refunds refunds:refundsList) {
                if (    refunds.getPaymentPluginId().equals("weixinPayPlugin") ||
                        refunds.getPaymentPluginId().equals("weixinMiniPayPlugin") ||
                        refunds.getPaymentPluginId().equals("balancePayPlugin")
                        ) {
                    amount = amount.add(refunds.getAmount()).subtract(refunds.getFee());
                }
            }

//            amount = amount.multiply(new BigDecimal(0.006)).setScale(2,BigDecimal.ROUND_HALF_DOWN);
//            cost = cost.multiply(new BigDecimal(0.006)).setScale(2,BigDecimal.ROUND_HALF_DOWN);

            if (cost.compareTo(BigDecimal.ZERO)>0) {
                depositService.decBalance(member.getId(), BigDecimal.ZERO.subtract(cost), 6, "货款-" + title, 0, askfor.getOrderId());
            }

            if (amount.compareTo(BigDecimal.ZERO)>0) {
                depositService.addBalance(member.getId(), BigDecimal.ZERO.subtract(amount), 4, "退款-" + askfor.getTitle(), 2, askfor.getOrderId());
            }


            //添加冻结

            BigDecimal freeze = amount.subtract(cost);
            if (freeze.compareTo(BigDecimal.ZERO)>0) {
                Order order = orderService.selectByPrimaryKey(askfor.getOrderId());
                if (DateUtils.truncate(order.getCreateDate(),Calendar.DATE).equals(DateUtils.truncate(new Date(),Calendar.DATE)))
                {
                    Map<String, Object> params = new HashMap<>();
                    params.put("id", member.getId());
                    params.put("value", freeze);
                    memberMapper.decFreezeBalance(params);
                }
            }

        }

    }

    public Integer calculatePoint(Askfor askfor) {
        Integer point = 0;
        for (AskforItem askforItem:askfor.getItemList()) {
            Product product = productService.selectByPrimaryKey(askforItem.getProductId());
            if (product.getType().equals(2)) {
                point = product.getPoint();
            }
        }

        return point;
    }

    /**
     * 确认退款
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public List<Refunds> refund(Long id,String sn) {

        //1、检查销售订单是否存在
        Askfor askfor = selectByPrimaryKey(id);
        if (null == askfor){
            throw new CustomException("未查找到订单");
        }

        if (askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_UNCONFIRM.getId()) || askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_REFUSED.getId()) || askfor.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_CANCLEED.getId())) {
            throw new CustomException("不能完成退款");
        }

        //3、更新order的shippingStatus状态
        askfor.setStatus(AskforStatusEnum.ASKFOR_STATUS_COMPLETE.getId());
        askfor.setItemList(askforItemService.getItemList(askfor.getId()));
        updateByPrimaryKeySelective(askfor);

        //扣减商品库存
        for (AskforItem sortItem:askfor.sortItemList()) {
            int r = productService.addStock(sortItem.getProductId(),sortItem.getQuantity());
        }

        //完成退款
        AskforLog askforLog = new AskforLog();
        askforLog.setAskforId(askfor.getId());
        askforLog.setCreateDate(new Date());
        askforLog.setContent("卖家已退款");
        askforLog.setType(AskforLogTypeEnum.ASKFOR_LOG_TYPE_COMPLETE.getId());
        askforLogService.insertUseGeneratedKeys(askforLog);

        OrderLog orderLog = new OrderLog();
        orderLog.setType(OrderLogTypeEnum.ORDER_LOG_TYPE_REFUND.getId());
        orderLog.setContent("卖家已退款");
        orderLog.setCreateDate(new Date());
        orderLog.setOrderId(askfor.getOrderId());
        orderLogService.insertUseGeneratedKeys(orderLog);

        Member member = memberService.selectByPrimaryKey(askfor.getMemberId());
        member.setAmount(member.getAmount().subtract(askfor.getAmountPayable()));
        memberService.updateByPrimaryKeySelective(member);

        //TODO
        //生成退款单

        BigDecimal amount = askfor.getAmountPayable();
        List<Refunds> refundList = new ArrayList<>();

        Map<String,Object> paymentParams = new HashMap<>();
        paymentParams.put("status",Payment.STATUS_SUCCESS);
        paymentParams.put("orderType",0);
        paymentParams.put("orderId",askfor.getOrderId());
        paymentParams.put("sortField", "id");
        paymentParams.put("sortType","desc");
        List<Payment> payments = paymentService.selectList(paymentParams);
        Integer w = 0;

        Refunds notifyRefund =  null;

        BigDecimal totalRefundAmount = BigDecimal.ZERO;

        Integer matchPoint = calculatePoint(askfor);
        if (matchPoint>0) {
            w ++;
            Refunds refunds = new Refunds();
            refunds.setCreateDate(new Date());
            refunds.setDeleted(false);
            refunds.setSn(sn+"-"+String.valueOf(w));
            refunds.setAmount(new BigDecimal(matchPoint/100));
            refunds.setFee(BigDecimal.ZERO);
            refunds.setAttach(null);
            refunds.setEnterpriseId(askfor.getEnterpriseId());
            refunds.setMemberId(askfor.getMemberId());
            refunds.setExpire(DateUtils.addMinutes(new Date(), 30));
            refunds.setStatus(Payment.STATUS_WAITING);
            refunds.setType(Payment.TYPE_ORDER);
            refunds.setMethod(Payment.METHOD_ONLINE);
            refunds.setMemo("退款-"+askfor.getTitle());
            refunds.setWay(1);
            refunds.setPaymentPluginId("matchPtPayPlugin");
            refunds.setPaymentPluginName("积分");
            refunds.setOrderType(OrderTypeEnum.ORDER_TYPE_ORDER.getId());
            refunds.setOrderId(askfor.getOrderId());
            refunds.setAskforId(askfor.getId());
            refunds.setQuantity(BigDecimal.ZERO);
            Attach attach = new Attach();

            attach.setId(String.valueOf(askfor.getOrderId()));
            attach.setCode("9999");
            attach.setQueue("queue.order.payment");
            attach.setDescription(askfor.getTitle());
            refunds.setAttach(JSON.toJSONString(attach));
            refundsService.insertUseGeneratedKeys(refunds);
            refundsService.execRefunds(refunds);
        }

        for (Payment payment:payments) {

            if ("matchPtPayPlugin".equals(payment.getPaymentPluginId())) {
                continue;
            }

            if (!payment.getStatus().equals(1)) {
                continue;
            }

            BigDecimal refundAmount = BigDecimal.ZERO;

            if (amount.compareTo(payment.canRefund())>0) {
                refundAmount = payment.canRefund();
            } else {
                refundAmount = amount;
            }

            totalRefundAmount = totalRefundAmount.add(refundAmount);

            if (refundAmount.compareTo(BigDecimal.ZERO)>0) {

                Refunds refunds = new Refunds();
                BeanUtils.copyProperties(payment, refunds);
                w ++ ;
                refunds.setSn(sn+"-"+String.valueOf(w));

                refunds.setMemo("退款-"+askfor.getTitle());
                refunds.setStatus(0);
                refunds.setPaymentId(payment.getId());
                refunds.setDeleted(false);


                refunds.setAmount(refundAmount);
                refunds.setFee(refundAmount.multiply(new BigDecimal(0.006)).setScale(2, BigDecimal.ROUND_HALF_DOWN));
                refunds.setAskforId(askfor.getId());

                Attach attachQueue = refunds.decodeAttach();
                if (attachQueue==null) {
                    attachQueue = new Attach();
                    attachQueue.setId(String.valueOf(payment.getOrderId()));
                    attachQueue.setCode("9999");
                    attachQueue.setQueue("queue.order.refunds");
                    attachQueue.setDescription(payment.getMemo());

                }

                if (attachQueue!=null) {
                    attachQueue.setQueue("queue.order.refunds");

                    refunds.setAttach(JSON.toJSONString(attachQueue));
                }

                refundsService.insertUseGeneratedKeys(refunds);

                payment.setRefund(refundAmount);
                paymentService.updateByPrimaryKeySelective(payment);

                if ("waterTicketPayPlugin".equals(payment.getPaymentPluginId())) {
                    virtualStockService.refunds(refunds);
                } else if ("couponCodePayPlugin".equals(payment.getPaymentPluginId())) {
                    couponCodeOrderService.refunds(refunds);
                } else {
                    refundsService.execRefunds(refunds);
                }

                amount = amount.subtract(refundAmount);

                if (!refunds.getStatus().equals(Refunds.STATUS_SUCCESS) && !refunds.getStatus().equals(Refunds.STATUS_REFUNDED)) {
                    refundList.add(refunds);
                } else {
                    notifyRefund = refunds;
                }

                if (amount.compareTo(BigDecimal.ZERO) <= 0) {
                    break;
                }

            }

        }

        startDistribution(askfor.getId());
        startCalcPoint(askfor.getId());

        virtualProductService.addAskfor(askfor);

        if (notifyRefund!=null) {
            try {
                refundsService.handle(notifyRefund.getSn(), null);
            } catch (Exception e) {
                throw new CustomException(e.getMessage());
            }
        }

        if (totalRefundAmount.compareTo(BigDecimal.ZERO)==0) {
            orderService.refundsHandle(askfor.getOrderId());
        }

        return refundList;

    }

}
